Skip to content

docs(spec): correct the published 17.4.0 entry that restated the retired M9.2 promise - #18569

Merged
os-bill merged 1 commit into
mainfrom
claude/issue-17849-changelog-erratum
Sep 17, 2026
Merged

os-bill merged 1 commit into
mainfrom
claude/issue-17849-changelog-erratum

Conversation

@os-bill

@os-bill os-bill commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator

Part of #17849

Clause-②: no

The second half of #17849, split out of PR #18557 because AGENTS.md's Documentation Guardrails row for packages/*/CHANGELOG.md requires it: an already-published entry is amended in a dedicated docs-only PR, ⛔ never as a rider on code changes. This diff is exactly one file and adds no source, no schema and no export.

#17323's ruling item 2 orders it: 「packages/spec/CHANGELOG.md: an erratum line under the entry that promised M9.2 (the #17026 shape — correct the published text, note the date), ⛔ not a rewrite of history.」

What was corrected, and where

One entry: ef3a138 (feat(spec)!: an evaluated expression slot requires a non-blank source) under the already-published ## 17.4.0. Line numbers re-derived on this tree at 79a046f8c, ⛔ not carried over from the card or from the earlier round:

line published text disposition
1096 the blockquote quoting EVALUATED_EXPRESSION_SOURCE_REQUIRED, parenthetical (the canonical persisted form of phase M9.1) left exactly as shipped — it is a faithful quote of what 17.4.0 published. A paragraph under it says what the constant reads now.
1103 「its docblock declares that ast becomes required in build output at phase M9.2」 corrected in place, old words kept as a marked quotation
1119 「has no evaluable form under M9.1」 corrected in place, old words kept as a marked quotation

One adjacent clause falsified by the same ruling is corrected in the same stroke and named here rather than smuggled: the bullet also read 「when AST-only evaluation lands」, which presupposes the retired promise. It now reads 「if AST-only evaluation is ever chartered」 — the wording the two pending changesets already carry. Leaving it would have left a 「when it lands」 sitting beside 「no promise of becoming required」 in one bullet.

One dated erratum line closes the entry, carrying the in-repo tail this repository already uses in five places (packages/spec/CHANGELOG.md ×3 at :2457, :2882, :5277, packages/lint/CHANGELOG.md:1214, packages/metadata-protocol/CHANGELOG.md:134):

*Erratum, 2026-09-17 — the M9.1 / M9.2 phase promise this entry restated was retired by the
ruling on #17323 (2026-09-12) … (Corrected after publication, #17849.)*

⛔ No new entry at the top, ⛔ no version heading added (git diff -U0 | grep -c '^+## ' → 0), ⛔ nothing this release published is changed.

⚠️ The card's grep criterion cannot be met, and the ruling is why

The card sets git grep -l 'M9\.[12]' origin/main -- packages → 0. After this PR that file still carries four hits, and every one of them is required by the ruling's own 「⛔ not a rewrite of history」:

:1096  the as-shipped blockquote                       (deliberately untouched)
:1109  "…becomes required in build output at phase M9.2"   inside `As published, that sentence continued "…"`
:1130  "no evaluable form under M9.1"                      inside `As published that clause read "…"`
:1142  the erratum line itself, naming the retired promise

Not one of them is a live assertion of the promise — they are the quotation marks the #17026 shape puts around it, plus the erratum that retires it. A zero would require deleting the published words, which is precisely the rewrite the ruling forbids. ⇒ the criterion and the ruling are not jointly satisfiable, and the ruling governs. Reported rather than forced.

⚠️ skip-changeset — checked against #18375 before relying on it

The label is applied. Before applying it I re-read the refusal #18375 is about, scripts/check-empty-changeset.mjs, and it does not reach this PR:

  • that gate has two rules and both take the .changeset/ diff and nothing else — rule 1 fires on a newly ADDED empty-frontmatter changeset, rule 2 (scanForeign()) on a MODIFIED or DELETED changeset that exists on the merge base;
  • the DELIBERATE-CORRECTION text 「no label and no diff shape makes that safe」 is scoped, in its own words, to 「the note you rewrote describes behaviour THIS PR changed」 — a pending release note, i.e. a .changeset/*.md;
  • this diff contains no .changeset/ path at all (git diff --name-only origin/main...HEAD → one line, packages/spec/CHANGELOG.md). So the label suppresses no refusal that could have fired here, and the finding's hazard is absent rather than accepted.

What the label IS doing is the documented job: Check Changeset requires an added changeset from every PR, with no path filter, so skip-changeset is the only instrument for a diff that releases nothing of its own — the same instrument the #17026 ruling named (item 3) and PR #17896 spent for the same shape.

Verification

Exit codes landed to disk before reading, ⛔ never through a pipe.

run verdict
derived gate families for this one path 55 derived · 51 run green · 4 NOT MEASURED
--ran reconciliation with per-family exit codes 55 derived famil(ies) accounted for — 51 run, 4 NOT-MEASURED (4 DERIVED from a recorded exit 3)
check-release-section-coverage (plain · --self-test · --strict) exit 0 ×3 — 7 published minors across 2 GA majors, every one still covered
pnpm check:release-notes, pnpm check:release-page-status exit 0
pnpm lint (eslint . --no-inline-config, whole repo) exit 0
pnpm check:nul-bytes + a direct control-character sweep of the file exit 0 / no hits

The 4 NOT MEASURED are check:dts-closure, check:dual-build-cjs-loads, check:lean-entry-closure and check:sourcemap-no-sources-content — all exit 3 = PREREQUISITE NOT MET (they read the dist/ of packages this tree never built). ⛔ Neither a pass nor a failure; CI's Build Core runs them.

No test is owed and that is measured, not assumed. Four test files name a CHANGELOG.md path and every one of them excludes it: compliance-families-retirement.test.ts skips CHANGELOG.md, both action-owner-key-single-source.test.ts files list it under covers as 「a published CHANGELOG is the record of the removal itself」, and template-consistency.test.ts passes :(exclude)**/CHANGELOG.md. No test reads the bytes this PR moves.

The changeset version survival question is already answered and is not re-run here. #17026's round measured it with a lit control: a manual edit inside an already-compiled section SURVIVES changeset version (marker present before and after, while the tool provably re-wrote both files — a new version section prepended, the package version advanced, 250 pending changesets consumed). That reading stands; re-running it would buy nothing.

Acceptance notes

Confirming reading for the finding recorded on #17849: pnpm check:cross-package-test-inputs is green (exit 0) on this tree, which has no packages/spec/dist because a markdown-only diff needs no build. Same gate, same commit base, opposite verdict from the built tree — a third independent leg for the same cause. ⛔ Not filed again; it is already #18353 and #18440.

Noted, not filed: nothing else. Successor for the M9.9b / M9.5 / M9.7 ROADMAP citations elsewhere in the tree: none — no PR or person is routed to those files by this work, and the ruling names only the M9.1 / M9.2 phase promise.


Generated by Claude Code

…romise

The `ef3a138` entry under `## 17.4.0` restates the M9.1 / M9.2 phase promise
that #17323's ruling retired: a two-phase roadmap chartered by no ADR. Three
passages are corrected in place in the #17026 shape — the published words are
kept as marked quotations, the correction follows each, and one dated erratum
line closes the entry.

The blockquote quoting `EVALUATED_EXPRESSION_SOURCE_REQUIRED` is left exactly
as 17.4.0 shipped it; a paragraph under it says what the constant reads now.
Nothing this release published is changed.

Claude-Session: https://claude.ai/code/session_01JbZnqu8bt6YqfJsr9vaFb3
Co-authored-by: Claude <noreply@anthropic.com>
@os-bill os-bill added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 17, 2026 — with Claude
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️ 1 changed file(s) yielded no anchor (packages/spec/CHANGELOG.md), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)).

What this run could not see
  • 1 changed file(s) yielded no anchor (packages/spec/CHANGELOG.md) — pages documenting those are invisible to this run
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 136 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 79a046f8cdf085d95200826ee9bb2fa6584bc3d5 → packageMentionDocs.

@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Sep 17, 2026
@os-bill
os-bill marked this pull request as ready for review September 17, 2026 02:08
@os-bill
os-bill enabled auto-merge September 17, 2026 02:09
@os-bill
os-bill added this pull request to the merge queue Sep 17, 2026
Merged via the queue into main with commit 298e9dd Sep 17, 2026
41 checks passed
@os-bill
os-bill deleted the claude/issue-17849-changelog-erratum branch September 17, 2026 02:29
akarma-synetal pushed a commit to akarma-synetal/framework that referenced this pull request Sep 28, 2026
…ed 17.0.0 and 17.0.0-rc.1 entries (objectstack-ai#18852)

Part of objectstack-ai#18740

> ⚠️ **Changed from `Fixes` to `Part of` by the dispatching
`domain:devx` seat.** Eight of the card's nine sites are corrected here.
The ninth — `content/docs/releases/v17/17-0.mdx:1734` — is still a live
carrier, and the delivering agent correctly declined it: its standing
operating rules prohibit editing `content/docs/releases/**`
unconditionally, and **a permission in AGENTS.md does not lift a
prohibition**. A closing keyword here would silently close a card that
still has an open half, so it is withdrawn. The ninth site is routed as
its own card; this PR stays a clean two-file CHANGELOG amendment.

A **dedicated docs-only PR**, which `AGENTS.md`'s Documentation
Guardrails row for `packages/*/CHANGELOG.md` requires: a factual error
in a released entry is amended *in that entry*, ⛔ never as an erratum in
a later entry and ⛔ never as a rider on code changes — "the reader greps
the tombstoned symbol and lands on the old entry, so a correction
anywhere else is one it never reaches".

The diff is exactly two files. No source, no schema, no export, no test,
and **no changeset** (see below).

## What was false

The 2026-09-07 ruling found that no reader of a published surface can
configure `batch.maxBatchSize`. The cap is **embedder policy**:
`RestServerConfig.batch.maxBatchSize` is the argument a host passes when
it constructs the server, through the one door `createRestApiPlugin({
api })`. Neither shipped boot path passes it — `os serve` forwards
exactly two keys out of the stack config's `api:` block
(`api.enableProjectScoping`, `api.projectResolution`), and the dev
plugin calls `createRestApiPlugin()` with no config at all. A
CLI-started deployment therefore always gets the 200 default, and no
flag, config file or CLI option moves it.

The `789ad63` entry carries that falsified claim in **two wordings**,
and it is duplicated under two published version headings, so there are
**eight** carriers, not four.

## The eight sites corrected

Located **by content, across lines** on this tree at `631dcbd4b` — ⛔ not
by the line numbers carried on the card, and ⛔ not with a single-line
match. The `Batch size is / deployment policy` sentence is **wrapped
across two lines**: a single-line grep for it returns 0 and reads as a
false absence.

| file | heading | wording |
|:--|:--|:--|
| `packages/rest/CHANGELOG.md` | `## 17.0.0` (L4733) | `should raise`
instruction + `deployment policy` |
| `packages/rest/CHANGELOG.md` | `## 17.0.0-rc.1` (L14992) | both |
| `packages/spec/CHANGELOG.md` | `## 17.0.0` (L15658) | both |
| `packages/spec/CHANGELOG.md` | `## 17.0.0-rc.1` (L67924) | both |

Per copy:

- **The claim.** `Batch size is deployment policy` now reads `Batch size
is embedder policy`, and the counterfactual beside it — `(a deployment
raising the limit to 500 would still have been refused at 200)` — now
says `a host`, since it presupposed the same unreachable knob.
- **The instruction.** The behaviour bullet read `Deployments that were
quietly relying on unbounded batches should raise` `batch.maxBatchSize`
`(up to 1000) rather than discover the cap in production`. That told an
operator to perform an action no shipped boot path can perform, so a
reader who complied had no way to tell whether they had succeeded. It
now states where the cap actually comes from and issues no instruction.

## Where this landed between "faithful to the record" and "no longer
misleading"

This is a CHANGELOG, so the job is to record what happened in that
version — ⛔ not to rewrite history into "this is what we said at the
time". I did not invent a shape for that: this repository has already
settled it, in objectstack-ai#18569 / objectstack-ai#17849, and I copied it. **The published words
are corrected in place, and the old words are kept as a marked quotation
in a dated erratum line closing the entry** — the in-repo tail already
used at `packages/spec/CHANGELOG.md` (three sites),
`packages/lint/CHANGELOG.md` and
`packages/metadata-protocol/CHANGELOG.md`. So the entry no longer
instructs, and what shipped is still readable verbatim.

The factual vocabulary is likewise copied, ⛔ not invented — from
`ec5db7b` (`packages/rest/CHANGELOG.md:351`) and the pending
`.changeset/18739-batch-cap-embedder-only.md`, which are the fourth and
fifth landings of this same correction.

⛔ No new entry at the top, ⛔ no version heading added, ⛔ nothing this
release published is changed: the 1..1000 range, the 200 default and the
enforcement are all untouched.

## ⛔ Deliberately no changeset

A changeset would compile this correction into a **new** release note —
which is precisely the erratum-in-a-later-entry shape `AGENTS.md`
forbids. Nothing published moves here either: the diff is prose inside
already-shipped entries.

## ⚠️ The ninth site is NOT in this PR — a standing-rule conflict I am
not resolving silently

`content/docs/releases/v17/17-0.mdx:1734` carries the same claim (`stay
under` `batch.maxBatchSize` `(default 200, raisable to 1000) or chunk`)
and the dispatch listed it as the ninth site.

I did not touch it. My standing operating rules carry an
**unconditional** prohibition on editing `content/docs/releases/`, and
they state that such a clause wins over the dispatch word. `AGENTS.md`
*permits* a docs-only PR there; it does not *require* one — a permission
does not override the prohibition, so there is no conflict with
`AGENTS.md`, only with the dispatch. Flagging rather than choosing a
side: that line is **still a live carrier** and needs either a separate
actor or an explicit release of the prohibition.

## ⚠️ Report item, ⛔ not fixed here

`packages/spec/CHANGELOG.md:3581` says the phrase "exists verbatim in
the REST server ... at `packages/rest/src/rest-server.ts:2071` ... it is
owed to a follow-up in `packages/rest`". Re-measured on `631dcbd4b`:
`grep -c "deployment policy" packages/rest/src/rest-server.ts` = **0**,
and `packages/rest/CHANGELOG.md:351` records `ec5db7b` retiring exactly
that phrase. **That follow-up is done and the note is now stale** — a
debt recorded as outstanding that has been paid. It is a different error
from the one this card names, so it is reported, ⛔ not ridden. `objectstack-ai#18740`
does not cover it.

## Firing controls

Computed from `git diff -U0` hunk headers so that context lines cannot
contaminate the reading, and taken from the probed files themselves.

- **C1** — `should raise` + `batch.maxBatchSize`: **0 outside the
diff**. Its only four hits are the verbatim quotations inside the new
erratum lines.
- **C2** — the batch-cap `deployment policy` claim, multiline-aware: 4
hits outside the diff, each classified and none a live carrier —
`packages/rest/CHANGELOG.md:351` (records the phrase's retirement),
`packages/spec/CHANGELOG.md:3581` (the stale note above),
`.changeset/18739-batch-cap-embedder-only.md` (the sibling correction),
`docs/qa/platform-checklist/FOLLOW-UPS.md:575` (states the correct
embedder-only fact).
- **C3** — the wrapped `Batch size is` / `deployment policy` sentence:
**0 hits anywhere in the tree**.
- Control bytes: `grep -naP` over both changed files exits 1 (no match).

A bare `deployment policy` string is ⛔ not a usable control — it matches
unrelated scheduling prose in about 30 files.

---
_Generated by [Claude
Code](https://claude.ai/code/session_017ef78bLdybu3AffehKkhfk)_

---
_Generated by [Claude Code](https://claude.ai/code)_

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants